package controllers;

import java.util.Iterator;
import java.util.Map;

import model.forview.NodeChangeModelForView;
import model.forview.NodeContentChangeModelForView;
import model.forview.NodeCreateModelForView;
import model.forview.NodeModelForView;
import model.forview.NodeOwnModelForView;
import model.forview.NodeRelationAddModelForView;
import model.forview.NodeRelationModelForView;
import model.forview.NodeSupervisingModelForView;
import model.forview.SearchModelForView;
import model.forview.StructureCreateModelForView;
import model.forview.StructuresModelForView;
import model.wrap.node.Node;
import model.wrap.structure.Structure;
import play.data.Form;
import play.mvc.Controller;
import play.mvc.Result;
import security.Security;
import security.SecurityException;

import views.html.all_structures;
import views.html.nodeRelation;
import views.html.nodeRelationAdd;
import views.html.structureCreate;
import views.html.nodeCreate;
import views.html.nodeContentChange;

/**
 * 
 * @author pocteg
 * 
 */
public class Hierarchy extends Controller
{

    public static Result structures(String query)
    {
	try
	{
	    Security.isAuthorize();

	    StructuresModelForView str = null;
	    if (null == query || query.equals("")) str = new StructuresModelForView(Structure.getAllStructures(), "");
	    else
		str = new StructuresModelForView(Structure.getStructuresByFilter(query), query);
	    return ok(all_structures.render(str));
	    // return redirect(routes.Application.getPageLogin());
	}
	catch (SecurityException sec)
	{
	    return redirect(routes.Application.getPageLogin());
	}
    }

    public static Result getPageStructureCreate()
    {
	StructureCreateModelForView forModel = new StructureCreateModelForView();
	return ok(structureCreate.render(forModel));
    }

    public static Result structureCreate()
    {
	// Form<StructureCreateModelForView> forModel =
	// form(StructureCreateModelForView.class).bindFromRequest();

	Structure str = new Structure(form().bindFromRequest().data());
	str.save();
	return redirect(routes.Hierarchy.structures(""));
    }

    public static Result getPageStructureDelete(Long idStructure)
    {
	Structure structure = new Structure(idStructure);
	StructureCreateModelForView modelForView = new StructureCreateModelForView(structure);
	return ok(views.html.structureDelete.render(modelForView));
    }

    public static Result structureDelete()
    {
	Map<String, String> form = form().bindFromRequest().data();
	Iterator<String> keys = form.keySet().iterator();
	while (keys.hasNext())
	{
	    String key = keys.next();
	    if (key.equals("data[id]"))
	    {
		(new Structure(Long.valueOf(form.get(key)))).delete();
		break;
	    }
	}

	return redirect(routes.Hierarchy.structures(""));
    }

    public static Result structureChange()
    {
	Structure str = new Structure(form().bindFromRequest().data());
	str.update();
	return redirect(routes.Hierarchy.structures(""));
    }

    public static Result getPageStructureChange(Long idStructure)
    {
	Structure structure = new Structure(idStructure);
	StructureCreateModelForView forModel = new StructureCreateModelForView(structure);
	return ok(structureCreate.render(forModel));
    }

    public static Result getPageSearch(String query)
    {
	SearchModelForView modelForView = new SearchModelForView(query);
	return ok(views.html.search.render(modelForView));
    }

    public static Result search()
    {
	return null;// ok(index.render("Your new application is ready."));
    }

    /**
     * # GET /node
     * 
     * @author pocteg
     * @param node
     * @return
     */
    public static Result node(Long node, Long structure)
    {
	NodeModelForView forModel;
	if (node.equals(new Long(0)))
	{
	    forModel = new NodeModelForView(new Structure(structure));
	    return ok(views.html.nodeRoot.render(forModel));
	}
	forModel = new NodeModelForView(Long.valueOf(node));
	return ok(views.html.node.render(forModel));
    }

    public static Result getPageNodeCreate(Long str)
    {
	NodeCreateModelForView forModel = new NodeCreateModelForView(str);
	return ok(nodeCreate.render(forModel));
    }

    public static Result nodeCreate()
    {
	Form<NodeCreateModelForView> forModel = form(NodeCreateModelForView.class).bindFromRequest();

	Node node = Node.createDraft(forModel.get());

	return redirect(routes.Hierarchy.getPageNodeContentChange(node.getId(), 1));
    }

    /**
     * /node/content/change
     * 
     * @author pocteg
     * @param idNode
     * @param isNew
     * @return
     */
    public static Result getPageNodeContentChange(Long idNode, Integer isNew)
    {
	Node node = new Node(idNode);

	NodeContentChangeModelForView forModel = new NodeContentChangeModelForView(node);

	if (isNew.equals(1))
	// TODO
	;

	return ok(nodeContentChange.render(forModel));
    }

    /**
     * GET /node/relation
     * 
     * @author pocteg
     * @param idNode
     * @return
     */
    public static Result getPageNodeRelation(Long idNode)
    {
	NodeRelationModelForView forModel = new NodeRelationModelForView(new Node(idNode));
	return ok(nodeRelation.render(forModel));
    }

    /**
     * GET
     * 
     * @author pocteg
     * @param idNode
     * @param idRelative
     * @return
     */
    public static Result getPageNodeRelationAdd(Long idNode, Long idRelative, Long idStructure)
    {
	Node relative;
	Structure structure;
	if (idRelative.equals(Long.valueOf(0))) relative = null;
	else
	    relative = new Node(idRelative);
	if (idStructure.equals(Long.valueOf(0))) structure = null;
	else
	    structure = new Structure(idStructure);
	NodeRelationAddModelForView forModel = new NodeRelationAddModelForView(new Node(idNode), relative, structure);
	return ok(nodeRelationAdd.render(forModel));
    }

    /**
     * POST
     * 
     * @author pocteg
     * @return
     */
    public static Result nodeRelationAdd()
    {
	Form<NodeRelationAddModelForView> forModel = form(NodeRelationAddModelForView.class).bindFromRequest();
	NodeRelationAddModelForView data = forModel.get();
	Node node = new Node(data.idNode);
	Node relative = new Node(data.idRelative);

	// TODO сообщить об ошибке
	// try
	// {
	if (data.type.equals(data.TYPE_C)) node.addChild(relative);
	else
	    node.addParent(relative);
	// }
	// catch (Exception e)
	// {
	// }

	return redirect(routes.Hierarchy.getPageNodeRelation(node.getId()));
    }

    public static Result getPageNodeDelete(Long idNode)
    {
	Node node = new Node(idNode);
	NodeModelForView modelForView = new NodeModelForView(node);
	return ok(views.html.nodeDelete.render(modelForView));
    }

    public static Result nodeDelete()
    {
	Map<String, String> form = form().bindFromRequest().data();
	Iterator<String> keys = form.keySet().iterator();
	Node node = null;
	Long strId;
	while (keys.hasNext())
	{
	    String key = keys.next();
	    if (key.equals("data[idNode]"))
	    {
		node = new Node(Long.valueOf(form.get(key)));
		break;
	    }
	}

	strId = Long.valueOf(node.getStructure().getId());
	node.delete();
	return redirect(routes.Hierarchy.node(Long.valueOf(0), strId));
    }

    public static Result getPageNodeChange(Long idNode)
    {
	Node node = new Node(idNode);
	NodeChangeModelForView model = new NodeChangeModelForView(node);
	return ok(views.html.nodeChange.render(model));
    }

    public static Result nodeChange()
    {
	NodeChangeModelForView model = new NodeChangeModelForView(form().bindFromRequest().data());
	Node node = new Node(model.nodeId);
	node.setTitle(model.title);
	node.update();
	return Hierarchy.node(node.getId(), node.getStructure().getId());
    }

    public static Result getPageOwnNode()
    {
	NodeOwnModelForView modelForView = new NodeOwnModelForView();
	return ok(views.html.nodeOwn.render(modelForView));
    }

    public static Result getPageNodeSupervising()
    {
	NodeSupervisingModelForView modelForView = new NodeSupervisingModelForView();
	return ok(views.html.nodeSupervising.render(modelForView));
    }

    public static Result nodeSupervisingConfirm(Long idNode)
    {
	Node node = new Node(idNode);
	node.setIsDraft(false);
	node.update();
	return redirect(routes.Hierarchy.getPageNodeSupervising());
    }

    public static Result nodeSupervisingReject(Long idNode)
    {
	Node node = new Node(idNode);
	node.setIsDraft(true);
	node.update();
	return redirect(routes.Hierarchy.getPageNodeSupervising());
    }

}
